package com.hulushuju.core.net.http.okhttp;

import com.hulushuju.core.net.cookie.CookieManager;
import com.hulushuju.core.net.cookie.okhttp.OkCookieManagerImpl;
import com.hulushuju.core.net.exception.HttpException;
import com.hulushuju.core.net.http.HttpClient;
import com.hulushuju.core.net.http.HttpRequest;
import com.hulushuju.core.net.http.HttpResponse;
import com.hulushuju.core.net.http.callback.HttpCallback;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import okhttp3.ConnectionPool;
import okhttp3.CookieJar;
import okhttp3.OkHttpClient;

import java.io.IOException;

/**
 * @Author: Hanjiafeng
 * @Date: 2019-05-29
 * @Desc: 使用OKHttp.Client实现发送
 */
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public class OkHttpClientImpl extends HttpClient {

    private OkHttpClient init() throws HttpException {
        //初始化请求对象
        httpRequest = HttpRequest.getInstance()
                .url(getUrl())
                .headers(headers)
                .method(getMethod())
                .contentType(getContentType())
                .formData(getFormData());

        //初始化CookieManager
        cookieManager = CookieManager.getInstance(OkCookieManagerImpl.class);
        CookieJar cookieJar = cookieManager.init(CookieJar.class);

        //初始化OKHttpClient
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
                .callTimeout(getTimeout(), timeUnit)
                .connectTimeout(getConnectTimeout(), timeUnit)
                .readTimeout(getReadTimeout(), timeUnit)
                .writeTimeout(getWriteTimeout(), timeUnit)
                .connectionPool(new ConnectionPool(getMaxIdleConnections(), getKeepAliveDuration(), timeUnit))
                .followRedirects(isFollowRedirects())
                .followSslRedirects(isFollowSslRedirects())
                .cookieJar(cookieJar);
        return clientBuilder.build();
    }

    @Override
    public HttpResponse execute() throws HttpException {
        OkHttpClient okHttpClient = init();
        httpEngine = new OkHttpEngineImpl(okHttpClient);
        HttpResponse httpResponse = null;
        HttpCallback httpCallback = getHttpCallback();
        try {
            httpResponse = httpEngine.execute(httpRequest);
            httpCallback.success(httpRequest, httpResponse);
        } catch (IOException e) {
            httpCallback.failure(httpRequest, e);
        }

        return httpResponse;
    }
}
